/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. *///// Eric Vaughan// Netscape Communications//// See documentation in associated header file//#include"gfxContext.h"#include"nsImageBoxFrame.h"#include"nsGkAtoms.h"#include"nsStyleContext.h"#include"nsStyleConsts.h"#include"nsStyleUtil.h"#include"nsCOMPtr.h"#include"nsPresContext.h"#include"nsBoxLayoutState.h"#include"nsHTMLParts.h"#include"nsString.h"#include"nsLeafFrame.h"#include"nsIPresShell.h"#include"nsIDocument.h"#include"nsImageMap.h"#include"nsILinkHandler.h"#include"nsIURL.h"#include"nsILoadGroup.h"#include"nsContainerFrame.h"#include"nsCSSRendering.h"#include"nsIDOMHTMLImageElement.h"#include"nsNameSpaceManager.h"#include"nsTextFragment.h"#include"nsIDOMHTMLMapElement.h"#include"nsTransform2D.h"#include"nsITheme.h"#include"nsIServiceManager.h"#include"nsIURI.h"#include"nsThreadUtils.h"#include"nsDisplayList.h"#include"ImageLayers.h"#include"ImageContainer.h"#include"nsIContent.h"#include"nsContentUtils.h"#include"mozilla/BasicEvents.h"#include"mozilla/EventDispatcher.h"#include"mozilla/Maybe.h"#include"SVGImageContext.h"#include"Units.h"#define ONLOAD_CALLED_TOO_EARLY 1usingnamespacemozilla;usingnamespacemozilla::gfx;usingnamespacemozilla::image;usingnamespacemozilla::layers;classnsImageBoxFrameEvent:publicRunnable{public:nsImageBoxFrameEvent(nsIContent*content,EventMessagemessage):mozilla::Runnable("nsImageBoxFrameEvent"),mContent(content),mMessage(message){}NS_IMETHODRun()override;private:nsCOMPtr<nsIContent>mContent;EventMessagemMessage;};NS_IMETHODIMPnsImageBoxFrameEvent::Run(){nsIPresShell*pres_shell=mContent->OwnerDoc()->GetShell();if(!pres_shell){returnNS_OK;}RefPtr<nsPresContext>pres_context=pres_shell->GetPresContext();if(!pres_context){returnNS_OK;}nsEventStatusstatus=nsEventStatus_eIgnore;WidgetEventevent(true,mMessage);event.mFlags.mBubbles=false;EventDispatcher::Dispatch(mContent,pres_context,&event,nullptr,&status);returnNS_OK;}// Fire off an event that'll asynchronously call the image elements// onload handler once handled. This is needed since the image library// can't decide if it wants to call its observer methods// synchronously or asynchronously. If an image is loaded from the// cache the notifications come back synchronously, but if the image// is loaded from the network the notifications come back// asynchronously.voidFireImageDOMEvent(nsIContent*aContent,EventMessageaMessage){NS_ASSERTION(aMessage==eLoad||aMessage==eLoadError,"invalid message");nsCOMPtr<nsIRunnable>event=newnsImageBoxFrameEvent(aContent,aMessage);nsresultrv=aContent->OwnerDoc()->Dispatch("nsImageBoxFrameEvent",TaskCategory::Other,event.forget());if(NS_FAILED(rv)){NS_WARNING("failed to dispatch image event");}}//// NS_NewImageBoxFrame//// Creates a new image frame and returns it//nsIFrame*NS_NewImageBoxFrame(nsIPresShell*aPresShell,nsStyleContext*aContext){returnnew(aPresShell)nsImageBoxFrame(aContext);}NS_IMPL_FRAMEARENA_HELPERS(nsImageBoxFrame)nsresultnsImageBoxFrame::AttributeChanged(int32_taNameSpaceID,nsIAtom*aAttribute,int32_taModType){nsresultrv=nsLeafBoxFrame::AttributeChanged(aNameSpaceID,aAttribute,aModType);if(aAttribute==nsGkAtoms::src){UpdateImage();PresContext()->PresShell()->FrameNeedsReflow(this,nsIPresShell::eStyleChange,NS_FRAME_IS_DIRTY);}elseif(aAttribute==nsGkAtoms::validate)UpdateLoadFlags();returnrv;}nsImageBoxFrame::nsImageBoxFrame(nsStyleContext*aContext):nsLeafBoxFrame(aContext,kClassID),mIntrinsicSize(0,0),mLoadFlags(nsIRequest::LOAD_NORMAL),mRequestRegistered(false),mUseSrcAttr(false),mSuppressStyleCheck(false){MarkIntrinsicISizesDirty();}nsImageBoxFrame::~nsImageBoxFrame(){}/* virtual */voidnsImageBoxFrame::MarkIntrinsicISizesDirty(){SizeNeedsRecalc(mImageSize);nsLeafBoxFrame::MarkIntrinsicISizesDirty();}voidnsImageBoxFrame::DestroyFrom(nsIFrame*aDestructRoot){if(mImageRequest){nsLayoutUtils::DeregisterImageRequest(PresContext(),mImageRequest,&mRequestRegistered);// Release image loader first so that it's refcnt can go to zeromImageRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);}if(mListener)reinterpret_cast<nsImageBoxListener*>(mListener.get())->SetFrame(nullptr);// set the frame to null so we don't send messages to a dead object.nsLeafBoxFrame::DestroyFrom(aDestructRoot);}voidnsImageBoxFrame::Init(nsIContent*aContent,nsContainerFrame*aParent,nsIFrame*aPrevInFlow){if(!mListener){RefPtr<nsImageBoxListener>listener=newnsImageBoxListener();listener->SetFrame(this);mListener=listener.forget();}mSuppressStyleCheck=true;nsLeafBoxFrame::Init(aContent,aParent,aPrevInFlow);mSuppressStyleCheck=false;UpdateLoadFlags();UpdateImage();}voidnsImageBoxFrame::UpdateImage(){nsPresContext*presContext=PresContext();RefPtr<imgRequestProxy>oldImageRequest=mImageRequest;if(mImageRequest){nsLayoutUtils::DeregisterImageRequest(presContext,mImageRequest,&mRequestRegistered);mImageRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);mImageRequest=nullptr;}// get the new image srcnsAutoStringsrc;mContent->GetAttr(kNameSpaceID_None,nsGkAtoms::src,src);mUseSrcAttr=!src.IsEmpty();if(mUseSrcAttr){nsIDocument*doc=mContent->GetComposedDoc();if(doc){nsContentPolicyTypecontentPolicyType;nsCOMPtr<nsIPrincipal>loadingPrincipal;nsContentUtils::GetContentPolicyTypeForUIImageLoading(mContent,getter_AddRefs(loadingPrincipal),contentPolicyType);nsCOMPtr<nsIURI>baseURI=mContent->GetBaseURI();nsCOMPtr<nsIURI>uri;nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),src,doc,baseURI);if(uri){nsresultrv=nsContentUtils::LoadImage(uri,mContent,doc,loadingPrincipal,doc->GetDocumentURI(),doc->GetReferrerPolicy(),mListener,mLoadFlags,EmptyString(),getter_AddRefs(mImageRequest),contentPolicyType);if(NS_SUCCEEDED(rv)&&mImageRequest){nsLayoutUtils::RegisterImageRequestIfAnimated(presContext,mImageRequest,&mRequestRegistered);}}}}else{// Only get the list-style-image if we aren't being drawn// by a native theme.uint8_tappearance=StyleDisplay()->mAppearance;if(!(appearance&&nsBox::gTheme&&nsBox::gTheme->ThemeSupportsWidget(nullptr,this,appearance))){// get the list-style-imageimgRequestProxy*styleRequest=StyleList()->GetListStyleImage();if(styleRequest){styleRequest->Clone(mListener,getter_AddRefs(mImageRequest));}}}if(!mImageRequest){// We have no image, so size to 0mIntrinsicSize.SizeTo(0,0);}else{// We don't want discarding or decode-on-draw for xul images.mImageRequest->StartDecoding(imgIContainer::FLAG_NONE);mImageRequest->LockImage();}// Do this _after_ locking the new image in case they are the same image.if(oldImageRequest){oldImageRequest->UnlockImage();}}voidnsImageBoxFrame::UpdateLoadFlags(){staticnsIContent::AttrValuesArraystrings[]={&nsGkAtoms::always,&nsGkAtoms::never,nullptr};switch(mContent->FindAttrValueIn(kNameSpaceID_None,nsGkAtoms::validate,strings,eCaseMatters)){case0:mLoadFlags=nsIRequest::VALIDATE_ALWAYS;break;case1:mLoadFlags=nsIRequest::VALIDATE_NEVER|nsIRequest::LOAD_FROM_CACHE;break;default:mLoadFlags=nsIRequest::LOAD_NORMAL;break;}}voidnsImageBoxFrame::BuildDisplayList(nsDisplayListBuilder*aBuilder,constnsRect&aDirtyRect,constnsDisplayListSet&aLists){nsLeafBoxFrame::BuildDisplayList(aBuilder,aDirtyRect,aLists);if((0==mRect.width)||(0==mRect.height)){// Do not render when given a zero area. This avoids some useless// scaling work while we wait for our image dimensions to arrive// asynchronously.return;}if(!IsVisibleForPainting(aBuilder))return;uint32_tclipFlags=nsStyleUtil::ObjectPropsMightCauseOverflow(StylePosition())?0:DisplayListClipState::ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT;DisplayListClipState::AutoClipContainingBlockDescendantsToContentBoxclip(aBuilder,this,clipFlags);nsDisplayListlist;list.AppendNewToTop(new(aBuilder)nsDisplayXULImage(aBuilder,this));CreateOwnLayerIfNeeded(aBuilder,&list);aLists.Content()->AppendToTop(&list);}DrawResultnsImageBoxFrame::PaintImage(gfxContext&aRenderingContext,constnsRect&aDirtyRect,nsPointaPt,uint32_taFlags){if(!mImageRequest){// This probably means we're drawn by a native theme.returnDrawResult::SUCCESS;}// Don't draw if the image's size isn't available.uint32_timgStatus;if(!NS_SUCCEEDED(mImageRequest->GetImageStatus(&imgStatus))||!(imgStatus&imgIRequest::STATUS_SIZE_AVAILABLE)){returnDrawResult::NOT_READY;}nsCOMPtr<imgIContainer>imgCon;mImageRequest->GetImage(getter_AddRefs(imgCon));if(!imgCon){returnDrawResult::NOT_READY;}Maybe<nsPoint>anchorPoint;nsRectdest=GetDestRect(aPt,anchorPoint);// don't draw if the image is not dirty// XXX(seth): Can this actually happen anymore?nsRectdirty;if(!dirty.IntersectRect(aDirtyRect,dest)){returnDrawResult::TEMPORARY_ERROR;}boolhasSubRect=!mUseSrcAttr&&(mSubRect.width>0||mSubRect.height>0);Maybe<SVGImageContext>svgContext;SVGImageContext::MaybeStoreContextPaint(svgContext,this,imgCon);returnnsLayoutUtils::DrawSingleImage(aRenderingContext,PresContext(),imgCon,nsLayoutUtils::GetSamplingFilterForFrame(this),dest,dirty,svgContext,aFlags,anchorPoint.ptrOr(nullptr),hasSubRect?&mSubRect:nullptr);}nsRectnsImageBoxFrame::GetDestRect(constnsPoint&aOffset,Maybe<nsPoint>&aAnchorPoint){nsCOMPtr<imgIContainer>imgCon;mImageRequest->GetImage(getter_AddRefs(imgCon));MOZ_ASSERT(imgCon);nsRectclientRect;GetXULClientRect(clientRect);clientRect+=aOffset;nsRectdest;if(!mUseSrcAttr){// Our image (if we have one) is coming from the CSS property// 'list-style-image' (combined with '-moz-image-region'). For now, ignore// 'object-fit' & 'object-position' in this case, and just fill our rect.// XXXdholbert Should we even honor these properties in this case? They only// apply to replaced elements, and I'm not sure we count as a replaced// element when our image data is determined by CSS.dest=clientRect;}else{// Determine dest rect based on intrinsic size & ratio, along with// 'object-fit' & 'object-position' properties:IntrinsicSizeintrinsicSize;nsSizeintrinsicRatio;if(mIntrinsicSize.width>0&&mIntrinsicSize.height>0){// Image has a valid size; use it as intrinsic size & ratio.intrinsicSize.width.SetCoordValue(mIntrinsicSize.width);intrinsicSize.height.SetCoordValue(mIntrinsicSize.height);intrinsicRatio=mIntrinsicSize;}else{// Image doesn't have a (valid) intrinsic size.// Try to look up intrinsic ratio and use that at least.imgCon->GetIntrinsicRatio(&intrinsicRatio);}aAnchorPoint.emplace();dest=nsLayoutUtils::ComputeObjectDestRect(clientRect,intrinsicSize,intrinsicRatio,StylePosition(),aAnchorPoint.ptr());}returndest;}voidnsDisplayXULImage::Paint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx){// Even though we call StartDecoding when we get a new image we pass// FLAG_SYNC_DECODE_IF_FAST here for the case where the size we draw at is not// the intrinsic size of the image and we aren't likely to implement predictive// decoding at the correct size for this class like nsImageFrame has.uint32_tflags=imgIContainer::FLAG_SYNC_DECODE_IF_FAST;if(aBuilder->ShouldSyncDecodeImages())flags|=imgIContainer::FLAG_SYNC_DECODE;if(aBuilder->IsPaintingToWindow())flags|=imgIContainer::FLAG_HIGH_QUALITY_SCALING;DrawResultresult=static_cast<nsImageBoxFrame*>(mFrame)->PaintImage(*aCtx,mVisibleRect,ToReferenceFrame(),flags);nsDisplayItemGenericImageGeometry::UpdateDrawResult(this,result);}nsDisplayItemGeometry*nsDisplayXULImage::AllocateGeometry(nsDisplayListBuilder*aBuilder){returnnewnsDisplayItemGenericImageGeometry(this,aBuilder);}voidnsDisplayXULImage::ComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion){autoboxFrame=static_cast<nsImageBoxFrame*>(mFrame);autogeometry=static_cast<constnsDisplayItemGenericImageGeometry*>(aGeometry);if(aBuilder->ShouldSyncDecodeImages()&&boxFrame->mImageRequest&&geometry->ShouldInvalidateToSyncDecodeImages()){boolsnap;aInvalidRegion->Or(*aInvalidRegion,GetBounds(aBuilder,&snap));}nsDisplayImageContainer::ComputeInvalidationRegion(aBuilder,aGeometry,aInvalidRegion);}boolnsDisplayXULImage::CanOptimizeToImageLayer(LayerManager*aManager,nsDisplayListBuilder*aBuilder){nsImageBoxFrame*imageFrame=static_cast<nsImageBoxFrame*>(mFrame);if(!imageFrame->CanOptimizeToImageLayer()){returnfalse;}returnnsDisplayImageContainer::CanOptimizeToImageLayer(aManager,aBuilder);}already_AddRefed<imgIContainer>nsDisplayXULImage::GetImage(){nsImageBoxFrame*imageFrame=static_cast<nsImageBoxFrame*>(mFrame);if(!imageFrame->mImageRequest){returnnullptr;}nsCOMPtr<imgIContainer>imgCon;imageFrame->mImageRequest->GetImage(getter_AddRefs(imgCon));returnimgCon.forget();}nsRectnsDisplayXULImage::GetDestRect(){Maybe<nsPoint>anchorPoint;returnstatic_cast<nsImageBoxFrame*>(mFrame)->GetDestRect(ToReferenceFrame(),anchorPoint);}boolnsImageBoxFrame::CanOptimizeToImageLayer(){boolhasSubRect=!mUseSrcAttr&&(mSubRect.width>0||mSubRect.height>0);if(hasSubRect){returnfalse;}returntrue;}//// DidSetStyleContext//// When the style context changes, make sure that all of our image is up to date.///* virtual */voidnsImageBoxFrame::DidSetStyleContext(nsStyleContext*aOldStyleContext){nsLeafBoxFrame::DidSetStyleContext(aOldStyleContext);// Fetch our subrect.constnsStyleList*myList=StyleList();mSubRect=myList->mImageRegion;// before |mSuppressStyleCheck| test!if(mUseSrcAttr||mSuppressStyleCheck)return;// No more work required, since the image isn't specified by style.// If we're using a native theme implementation, we shouldn't draw anything.constnsStyleDisplay*disp=StyleDisplay();if(disp->mAppearance&&nsBox::gTheme&&nsBox::gTheme->ThemeSupportsWidget(nullptr,this,disp->mAppearance))return;// If list-style-image changes, we have a new image.nsCOMPtr<nsIURI>oldURI,newURI;if(mImageRequest)mImageRequest->GetURI(getter_AddRefs(oldURI));if(myList->GetListStyleImage())myList->GetListStyleImage()->GetURI(getter_AddRefs(newURI));boolequal;if(newURI==oldURI||// handles null==null(newURI&&oldURI&&NS_SUCCEEDED(newURI->Equals(oldURI,&equal))&&equal))return;UpdateImage();}// DidSetStyleContextvoidnsImageBoxFrame::GetImageSize(){if(mIntrinsicSize.width>0&&mIntrinsicSize.height>0){mImageSize.width=mIntrinsicSize.width;mImageSize.height=mIntrinsicSize.height;}else{mImageSize.width=0;mImageSize.height=0;}}/** * Ok return our dimensions */nsSizensImageBoxFrame::GetXULPrefSize(nsBoxLayoutState&aState){nsSizesize(0,0);DISPLAY_PREF_SIZE(this,size);if(DoesNeedRecalc(mImageSize))GetImageSize();if(!mUseSrcAttr&&(mSubRect.width>0||mSubRect.height>0))size=mSubRect.Size();elsesize=mImageSize;nsSizeintrinsicSize=size;nsMarginborderPadding(0,0,0,0);GetXULBorderAndPadding(borderPadding);size.width+=borderPadding.LeftRight();size.height+=borderPadding.TopBottom();boolwidthSet,heightSet;nsIFrame::AddXULPrefSize(this,size,widthSet,heightSet);NS_ASSERTION(size.width!=NS_INTRINSICSIZE&&size.height!=NS_INTRINSICSIZE,"non-intrinsic size expected");nsSizeminSize=GetXULMinSize(aState);nsSizemaxSize=GetXULMaxSize(aState);if(!widthSet&&!heightSet){if(minSize.width!=NS_INTRINSICSIZE)minSize.width-=borderPadding.LeftRight();if(minSize.height!=NS_INTRINSICSIZE)minSize.height-=borderPadding.TopBottom();if(maxSize.width!=NS_INTRINSICSIZE)maxSize.width-=borderPadding.LeftRight();if(maxSize.height!=NS_INTRINSICSIZE)maxSize.height-=borderPadding.TopBottom();size=nsLayoutUtils::ComputeAutoSizeWithIntrinsicDimensions(minSize.width,minSize.height,maxSize.width,maxSize.height,intrinsicSize.width,intrinsicSize.height);NS_ASSERTION(size.width!=NS_INTRINSICSIZE&&size.height!=NS_INTRINSICSIZE,"non-intrinsic size expected");size.width+=borderPadding.LeftRight();size.height+=borderPadding.TopBottom();returnsize;}if(!widthSet){if(intrinsicSize.height>0){// Subtract off the border and padding from the height because the// content-box needs to be used to determine the rationscoordheight=size.height-borderPadding.TopBottom();size.width=nscoord(int64_t(height)*int64_t(intrinsicSize.width)/int64_t(intrinsicSize.height));}else{size.width=intrinsicSize.width;}size.width+=borderPadding.LeftRight();}elseif(!heightSet){if(intrinsicSize.width>0){nscoordwidth=size.width-borderPadding.LeftRight();size.height=nscoord(int64_t(width)*int64_t(intrinsicSize.height)/int64_t(intrinsicSize.width));}else{size.height=intrinsicSize.height;}size.height+=borderPadding.TopBottom();}returnBoundsCheck(minSize,size,maxSize);}nsSizensImageBoxFrame::GetXULMinSize(nsBoxLayoutState&aState){// An image can always scale down to (0,0).nsSizesize(0,0);DISPLAY_MIN_SIZE(this,size);AddBorderAndPadding(size);boolwidthSet,heightSet;nsIFrame::AddXULMinSize(aState,this,size,widthSet,heightSet);returnsize;}nscoordnsImageBoxFrame::GetXULBoxAscent(nsBoxLayoutState&aState){returnGetXULPrefSize(aState).height;}#ifdef DEBUG_FRAME_DUMPnsresultnsImageBoxFrame::GetFrameName(nsAString&aResult)const{returnMakeFrameName(NS_LITERAL_STRING("ImageBox"),aResult);}#endifnsresultnsImageBoxFrame::Notify(imgIRequest*aRequest,int32_taType,constnsIntRect*aData){if(aType==imgINotificationObserver::SIZE_AVAILABLE){nsCOMPtr<imgIContainer>image;aRequest->GetImage(getter_AddRefs(image));returnOnSizeAvailable(aRequest,image);}if(aType==imgINotificationObserver::DECODE_COMPLETE){returnOnDecodeComplete(aRequest);}if(aType==imgINotificationObserver::LOAD_COMPLETE){uint32_timgStatus;aRequest->GetImageStatus(&imgStatus);nsresultstatus=imgStatus&imgIRequest::STATUS_ERROR?NS_ERROR_FAILURE:NS_OK;returnOnLoadComplete(aRequest,status);}if(aType==imgINotificationObserver::IS_ANIMATED){returnOnImageIsAnimated(aRequest);}if(aType==imgINotificationObserver::FRAME_UPDATE){returnOnFrameUpdate(aRequest);}returnNS_OK;}nsresultnsImageBoxFrame::OnSizeAvailable(imgIRequest*aRequest,imgIContainer*aImage){NS_ENSURE_ARG_POINTER(aImage);// Ensure the animation (if any) is started. Note: There is no// corresponding call to Decrement for this. This Increment will be// 'cleaned up' by the Request when it is destroyed, but only then.aRequest->IncrementAnimationConsumers();nscoordw,h;aImage->GetWidth(&w);aImage->GetHeight(&h);mIntrinsicSize.SizeTo(nsPresContext::CSSPixelsToAppUnits(w),nsPresContext::CSSPixelsToAppUnits(h));if(!(GetStateBits()&NS_FRAME_FIRST_REFLOW)){PresContext()->PresShell()->FrameNeedsReflow(this,nsIPresShell::eStyleChange,NS_FRAME_IS_DIRTY);}returnNS_OK;}nsresultnsImageBoxFrame::OnDecodeComplete(imgIRequest*aRequest){nsBoxLayoutStatestate(PresContext());this->XULRedraw(state);returnNS_OK;}nsresultnsImageBoxFrame::OnLoadComplete(imgIRequest*aRequest,nsresultaStatus){if(NS_SUCCEEDED(aStatus)){// Fire an onload DOM event.FireImageDOMEvent(mContent,eLoad);}else{// Fire an onerror DOM event.mIntrinsicSize.SizeTo(0,0);PresContext()->PresShell()->FrameNeedsReflow(this,nsIPresShell::eStyleChange,NS_FRAME_IS_DIRTY);FireImageDOMEvent(mContent,eLoadError);}returnNS_OK;}nsresultnsImageBoxFrame::OnImageIsAnimated(imgIRequest*aRequest){// Register with our refresh driver, if we're animated.nsLayoutUtils::RegisterImageRequest(PresContext(),aRequest,&mRequestRegistered);returnNS_OK;}nsresultnsImageBoxFrame::OnFrameUpdate(imgIRequest*aRequest){if((0==mRect.width)||(0==mRect.height)){returnNS_OK;}InvalidateLayer(nsDisplayItem::TYPE_XUL_IMAGE);returnNS_OK;}NS_IMPL_ISUPPORTS(nsImageBoxListener,imgINotificationObserver,imgIOnloadBlocker)nsImageBoxListener::nsImageBoxListener(){}nsImageBoxListener::~nsImageBoxListener(){}NS_IMETHODIMPnsImageBoxListener::Notify(imgIRequest*request,int32_taType,constnsIntRect*aData){if(!mFrame)returnNS_OK;returnmFrame->Notify(request,aType,aData);}NS_IMETHODIMPnsImageBoxListener::BlockOnload(imgIRequest*aRequest){if(mFrame&&mFrame->GetContent()&&mFrame->GetContent()->GetUncomposedDoc()){mFrame->GetContent()->GetUncomposedDoc()->BlockOnload();}returnNS_OK;}NS_IMETHODIMPnsImageBoxListener::UnblockOnload(imgIRequest*aRequest){if(mFrame&&mFrame->GetContent()&&mFrame->GetContent()->GetUncomposedDoc()){mFrame->GetContent()->GetUncomposedDoc()->UnblockOnload(false);}returnNS_OK;}